package fireway;

/**
 * 分隔符匹配
 * 2018年 03月 25日 星期日
 *
 * @author fireway
 */
public class BracketChecker {
    private BracketChecker() {

    }

    public static boolean check(String input) throws MismatchException {
        int size = input.length();
        StackX stackX = new StackX(size);

        for (int i = 0; i < size; i++) {
            char current = input.charAt(i);
            switch (current) {
                case '{':
                case '[':
                case '(':
                    stackX.push(current);
                    break;

                case '}':
                case ']':
                case ')': {
                    if (!stackX.empty()) {
                        char pop = stackX.pop();
                        if (!match(current, pop)) {
                            throw new MismatchException("Error1: " + current + " at " + i);
                        }

                    } else {  // prematurely empty
                        throw new MismatchException("Error2: " + current + " at " + i);
                    }
                }
                break;
                default:
                    // nothing
                    break;
            }
        }

        // at this point, all characters have been processed
        if (!stackX.empty()) {
            throw new MismatchException("Error3: missing right delimiter");
        }

        return true;
    }

    private static boolean match(char current, char pop) {
        if ('}' == current) {
            return '{' == pop;
        } else if (']' == current) {
            return '[' == pop;
        } else if (')' == current) {
            return '(' == pop;
        }
        return false;
    }

    private static class StackX {
        private char[] mCArray;

        private int mTop;

        public StackX(int initialCapacity) {
            mCArray = new char[initialCapacity];
            mTop = -1;
        }

        public void push(char item) {
            if (full()) {
                System.out.println("Can't insert, stack is full");
                return;
            }

            mCArray[++mTop] = item;
        }

        public char pop() {
            if (empty()) {
                System.out.println("Can't pop, stack is empty");
                return 0;
            }

            char temp = mCArray[mTop];
            mTop--;
            return temp;
        }

        public char peek() {
            return mCArray[mTop];
        }

        public boolean empty() {
            return (-1 == mTop);
        }

        private boolean full() {
            return (mCArray.length - 1 == mTop);
        }
    }

    public static class MismatchException extends Exception {
        private static final long serialVersionUID = 1L;

        public MismatchException(String s) {
            super(s);
        }
    }
}
